#include <EEPROM.h>

/*
  Memo_int
  Memorizza un intero nella memoria non volatile.
  1 bottone e 1 led.
  SEQUENZA ACCENSIONE: 2 lampeggi veloci + lampeggia tante volte quanto è il numero memorizzato (3 default)
  
  1) Premendo il tasto a lungo si entra in programmazione
   - due lampeggi voloci
   - si preme il tasto il numero di volte da memeorizzare
   - quando non si preme più per un po' di tempo il dato viene memorizzato -> ripete SEQUENZA ACCENSIONE
   - se, una volta entrati in programmazione, non si preme -> viene lasciato il valore precedente
 */
 
 const int LED_PIN = 6;
 const int BUTTON_PIN = 13;
 
 const int EEPROM_ADDRESS = 50;
 
 const unsigned long LONG_TIME_PRESSION_MILLIS = 3000UL;
 const unsigned long EXIT_PROGRAMMING_MILLIS = 6000UL;

 const unsigned int MAX_VAL = 9;
 const unsigned int DEFAULT_VAL = 3;


 
 //Button state
 unsigned int button_prev = LOW; 
 unsigned long button_first_time_pression_millis = 0;
 unsigned long button_long_time_pression_millis = 0;


 boolean state_programming = false;
 unsigned long last_programming_event_millis = 0;

 
 unsigned int val = DEFAULT_VAL;
 unsigned int new_val = 0;
 
 void setup() 
 {      
   pinMode(LED_PIN, OUTPUT);
   pinMode(BUTTON_PIN, INPUT);
   
   //EEPROM.write(EEPROM_ADDRESS, 4);
   //delay(500);
   
   val = EEPROM.read(EEPROM_ADDRESS);
   if(val>MAX_VAL)
     val = DEFAULT_VAL;
       
   fastBlink();
   delay(250);
   blinkForValue();
 }

 void loop() 
 {
  unsigned long current_time_millis = millis();
  
  int button = digitalRead(BUTTON_PIN);
  if ((button == HIGH) && (button_prev == LOW)) //Tasto premuto per la prima volta
  {
    button_first_time_pression_millis = current_time_millis;
    if(state_programming)
    {
      last_programming_event_millis = current_time_millis;
      digitalWrite(LED_PIN, HIGH);
      delay(50);
      digitalWrite(LED_PIN, LOW);
      new_val++;
    }
    delay(250);
  }
  
  if(!state_programming) //Verifico le condizioni per entrare in programmazione
  {
    if ((button == HIGH) && (button_prev == HIGH)) //Tasto premuto ancora
    {
      if(current_time_millis-button_first_time_pression_millis > LONG_TIME_PRESSION_MILLIS) //long time pression millis
      {
        fastBlink();
        state_programming = true;
        new_val = 0;
        last_programming_event_millis = current_time_millis;
        delay(100);
      }
    }
  }
  else 
  {
    //Verifico le condizioni per uscire dalla programmazione
    if(button==LOW) //!!!!!!!!!!!!!!
    {
      if(current_time_millis-last_programming_event_millis>EXIT_PROGRAMMING_MILLIS) //non premo il tasto da un tot
      {
         fastBlink();
         delay(250);  
         state_programming = false;
         if(new_val>0)
         {
           if(val!=new_val)
           {
             val = new_val;
             EEPROM.write(EEPROM_ADDRESS, val);
           }
         }
         blinkForValue();
         //delay(250);         
      }
    }
    
  }
 
  //Aggiorno il valore precedente 
  button_prev = button;
  //delay(50);   
}

 void fastBlink()
 {
   for(int i = 0; i <2; i++)
   {
     digitalWrite(LED_PIN, HIGH);
     delay(100);
     digitalWrite(LED_PIN, LOW);
     delay(100);
   } 
 }

 void blinkForValue()
 {
  digitalWrite(LED_PIN, LOW);
  delay(100);
  
  for(int i = 0; i <val; i++)
  {
    digitalWrite(LED_PIN, HIGH);
    delay(250);
    digitalWrite(LED_PIN, LOW);
    delay(250);
  } 
 }

 void lightOn()
 {
   digitalWrite(LED_PIN, HIGH);
 }

 void lightOff()
 {
   digitalWrite(LED_PIN, LOW);
 }

